Chciałbym pokazać porównanie między modelem zbudowanym na danych podanych, a modelem zbudowanym na danych stoworzonych przeze mnie na podstawie danych podanych. Jako wyznacznik będę uważał, błąd podany w treści zadania.
W całym zadaniu będę używał algorytmu lasów losowych: randomForest. Dane prezentują się następująco:
train <- read.csv("train.csv")
modelsFull1 <- cbind(train, dummy(train$DepartmentDescription, sep = "_"))
modelsFull2 <- modelsFull1
train
W związku z tym, że randomForest nie działa, gdy jakaś kolumna kategoryczna ma więcej niż 53 poziomy, zdecydowałem się do ograniczenia ilości poziomów DepartamentDescription do 51, wykonałem to sposobem z poprzedniej pracy domowej (za pomocą funkcji fct_lump() z pakietu forcats). W celach uczenia i testowania modelu, podzieliłem zbiór danych w proporcji 75/25. Dzięki temu wytrenowałem model i byłem w stanie obliczyć błąd. Wyszedł on całkiem duży.
blad_przed
## [1] 1.957085
W celu polepszenia jakości predykcji zdecydowałem się, stworzyć pięć nowych kolumny:
AllProducts - ile wszystkich produktów brało udział w tranzakcji,BoughtProducts - ile produktów kupiono w danej tranzakcji,ReturnedProducts - ile produktów zwrócono w danej tranzakcji,DepartmentNumber - numer świadczący o tym, w ilu departamentach robione były zakupy,FinelineNumber - numer świadczący o tym, ile finelinenumber brało udział w tranzakcji.Połączyłem to jeszcze z przekodowanymi zmiennymi, dotyczącymi DepartamentDescription. To tego kodowania użyłem dummy Variables z pakietu dummies. Na uzyskanych w ten sposób zmiennych zrobiłem jeszcze agregacje, która pokazuje ile raz konkretny departament był odwiedzany w każdej tranzakcji.
Dane prezentują się następująco:
data1 <- modelsFull1 %>%
group_by(VisitNumber) %>%
summarise(TripType = as.factor(head(TripType,1)),
AllProducts = sum(ScanCount),
BoughtProducts = sum(ScanCount >= 0),
ReturnedProducts = sum(ScanCount < 0),
DepartmentNumber = n_distinct(DepartmentDescription),
FinelineNumber = n_distinct(FinelineNumber)
)
data2 <- select(modelsFull2, -c(1,3,4,5,6,7)) %>%
group_by(VisitNumber) %>%
summarise_all(sum)
data1 <- as.data.frame(data1)
data2 <- as.data.frame(data2)
data <- data.frame(merge(data1, data2, by = "VisitNumber"))
data
Dzięki temu udało mi się wytrenować nowy model i przeprowadzić kolejne testy. Tym razem błąd wyszedł.
blad
## [1] 0.9282847
Jak widzimy wyszedł mniejszy o ponad 1. Biorąc pod uwagę to w jaki sposób błąd jest wyliczany można powiedzieć, że jest to znacząca poprawa.
Widzimy, że feature engineering znacznie polepszył jakość naszej predykcji. Sprawdźmy wykres ważnosći poszczególnych zmiennych, aby to zweryfikować.
knitr::include_graphics("wykres.png")
Jak widać z wykresu, najważniejsze są zmienne, które zostały stworzone przeze mnie, zatem wiemy, że polepszenie błędu nie jest przypadkiem.